package com.spsyry.pay.conteoller;

import com.spsyry.common.core.domain.R;
import com.spsyry.pay.domain.PaymentOrder;
import com.spsyry.pay.enums.PayOrderEnum;
import com.spsyry.pay.order.WeiXinUtil;
import com.spsyry.pay.service.IPaymentOrderService;
import com.spsyry.pay.vo.OrderVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/pay")
@Slf4j
public class PaymentController
{
    @Autowired
    private IPaymentOrderService paymentOrderService;

    @PostMapping("/create")
    public R createOrder(@RequestBody OrderVo orderVo) throws Exception {
        PaymentOrder paymentOrder = PaymentOrder.builder()
                .errorCode("A")
                .orderNo(UUID.randomUUID().toString())
                .notifyUrl("url")
                .errorMessage("1")
                .expireTime(new Date())
                .payAmount(new BigDecimal(12))
                .payMethod("payMethod")
                .userIp("ip")
                .notifyStatus(PayOrderEnum.NOTPAY.getDescription())
                .payTime(new Date())
                .merchantOrderNo(orderVo.getOrderId())
                .build();
        String random = RandomStringUtils.random(5);

        System.out.println(random);

        Integer save = paymentOrderService.insertPaymentOrder(paymentOrder);

        String payOrder = WeiXinUtil.payOrder(orderVo.getOrderId());

        return R.ok(payOrder);
    }


    @PostMapping("/creates")
    public R createOrderWeiXin(@RequestBody OrderVo orderVo) throws Exception {
        PaymentOrder paymentOrder = PaymentOrder.builder()
                .errorCode("A")
                .orderNo(UUID.randomUUID().toString())
                .notifyUrl("url")
                .errorMessage("1")
                .expireTime(new Date())
                .payAmount(new BigDecimal(12))
                .payMethod("payMethod")
                .userIp("ip")
                .notifyStatus(PayOrderEnum.SUCCESS.getDescription())
                .payTime(new Date())
                .build();
        String random = RandomStringUtils.random(5);

        System.out.println(random);

        Integer save = paymentOrderService.insertPaymentOrder(paymentOrder);


        //String payOrder = WeiXinUtil.payOrder(orderVo.getOrderId());
        String pay = AlipayNotifyController.pay(null, orderVo.getOrderId());
        return R.ok(pay);
    }



    //不加锁
    @PostMapping("/statistics")
    public R statistics(){
        int number = 0;

        for (int i = 0; i <= 10000; i++) {
            number = number + 1;
        }
        return R.ok(number);
    }

    private static int n = 0;
    //锁对象（必须是所有线程共享的对象）
    private static final Object lock = new Object();

    @PostMapping("/synchronizedStatistics")
    public R synchronizedStatistics() throws InterruptedException {
        //创建一个包含 10 个固定线程的线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(10);

        for (int i = 0; i <= 10000; i++) {
            threadPool.submit(()->{
                //同步代码块，保证同一时间只有一个线程执行
                //同步锁
                synchronized(lock){
                    n = n + 1;
                }
            });
        }
        threadPool.shutdown();
        //启动线程池的 "平缓关闭" 流程。
        threadPool.awaitTermination(1, TimeUnit.MINUTES);
        //阻塞当前线程（通常是主线程），等待线程池完全关闭。（一分钟）

        //这两行代码通常一起使用，实现 "先禁止新任务进入，再等待已有任务完成" 的完整关闭流程，确保：
        //所有提交的任务都能被执行（不会丢失）。
        //主线程会等待任务全部完成后再继续执行（避免程序提前退出导致任务中断）。
        return R.ok("多线程加锁最终结果：" + n);
    }

    @PostMapping("/synchronizedStatisticsNo")
    public R synchronizedStatisticsNo() throws InterruptedException {
        //创建一个包含 10 个固定线程的线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(10);

        for (int i = 0; i <= 10000; i++) {
            threadPool.submit(()->{
                n = n + 1;
            });
        }
        threadPool.shutdown();
        //启动线程池的 "平缓关闭" 流程。
        threadPool.awaitTermination(1, TimeUnit.MINUTES);
        //阻塞当前线程（通常是主线程），等待线程池完全关闭。（一分钟）

        //这两行代码通常一起使用，实现 "先禁止新任务进入，再等待已有任务完成" 的完整关闭流程，确保：
        //所有提交的任务都能被执行（不会丢失）。
        //主线程会等待任务全部完成后再继续执行（避免程序提前退出导致任务中断）。
        return R.ok("多线程不加锁最终结果：" + n);
    }
}
